3.1. Root Resource Classes 根资源类
Root Resource Classes 是带有 @PATH 注解的,包含至少一个 @PATH 注解的方法或者方法带有 @GET、@PUT、 @POST、 @DELETE 资源方法指示器的 POJO。资源方法是带有资源方法指示器(resource method designator)注解的方法。这一节就是展示如何使用 Java 对象内的注解创建一个 Jersey 的 RESTful 服务。
下面这段代码就是一个带有 JAX-RS 注解的简单示例,可以从这里下载。
Example 3.1. 简单hello world根资源类例子
package org.glassfish.jersey.examples.helloworld;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("helloworld")
public class HelloWorldResource {
public static final String CLICHED_MESSAGE = "Hello World!";
@GET
@Produces("text/plain")
public String getHello() {
return CLICHED_MESSAGE;
}
}
下面看下 JAX-RS 里面的几个注解
3.1.1. @Path
@PATH 是一个URI的相对路径,在上面的例子中,设置的是本地的 URI 的 /helloworld
。这事一个非常简单的关于 @PATH的例子,更有用的是你可以嵌入变量到 URIs 里面
URI 的路径模版是由 URIs 和嵌入 URI 语法的变量组成。变量在运行时将会被匹配到的 URI 的那部分多代替。例如下面的 @Path 注解
@Path("/users/{username}")
按照这种类型的例子,一个用户会方便的填写他的名字,那么 Jersey 服务器也会按照这个 UIR 路径模板响应到这个请求。例如:用户输入了名字“Galileo”,那么服务器就会响应 http://example.com/users/Galileo
。
为了接收到用户名变量,@PathParam 用在接收请求的方法的参数上,例如:
Example 3.2. 指定的URI路径参数
@Path("/users/{username}")
public class UserResource {
@GET
@Produces("text/xml")
public String getUser(@PathParam("username") String userName) {
...
}
}
它规定匹配正则表达式式要精确到大小写的,如果填写的话会覆盖默认的表达式 [^/]+?
,例如
@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]*}")
这个正则表达式匹配由大小写字符、横杠和数字组成的字符串,如果正则校验不通过,则返回404
(没有找到资源)。
一个 @Path的内容是否以”/“开头都没有区别,同样是否以”/“结尾也没有什么区别
3.1.2. @GET, @PUT, @POST, @DELETE, … (HTTP 方法)
@GET, @PUT, @POST, @DELETE, @HEAD 是JAX-RS 定义的注解,它非常类似与 HTTP 的方法名。在上面的例子中,这些注解是通过HTTP的 GET 方法实现的。资源的响应就是HTTP的响应。
下面这个例子是存储服务的一个片段,是使用 PUT 方法处理创建或者修改存储容器:
Example 3.3. PUT 方法
@PUT
public Response putContainer() {
System.out.println("PUT CONTAINER " + container);
URI uri = uriInfo.getAbsolutePath();
Container c = new Container(container, uri.toString());
Response r;
if (!MemoryStore.MS.hasContainer(c)) {
r = Response.created(uri).build();
} else {
r = Response.noContent().build();
}
MemoryStore.MS.createContainer(c);
return r;
}
如果没有明确的定义的话,JAX-RS 运行的时候默认支持 HEAD 和 OPTIONS 方法。HEAD 运行时将调用 get 方法的实现(如果存在)和忽略响应实体(如果设置)。一个响应返回 OPTIONS 的方法取决于所要求的媒体类型在头文件中 ‘Accept’ 的定义。 OPTIONS 方法可以返回一组支持资源的方法在 头文件中 ‘Allow’ 或返回 WADL 文件的进行设置。更多信息见https://jersey.java.net/documentation/latest/wadl.html节。
3.1.3. @Produces
@Produces是定义返回值给客户端的 MIME 媒体类型。在下面这个例子里面,将会返回一个对应于text/plain
的 MIME 媒体类型。@Produces 既可以应用在类上,也可以作用于方法上。这里是一个例子:
Example 3.4. 指定输出文件的MIME类型
@Path("/myResource")
@Produces("text/plain")
public class SomeResource {
@GET
public String doGetAsPlainText() {
...
}
@GET
@Produces("text/html")
public String doGetAsHtml() {
...
}
}
这个 doGetAsPlainText 方法默认使用类水平的 @Produces 注解内容,也就是text/plain
。而 doGetAsHtml 方法使用方法水平上的@Produces,也就是text/html
。也就是说方法水平层面的@Produces 会覆盖类层面的@Produces。
如果一个资源类是能够生产多个 MIME 媒体类型,资源的方法的响应将会对应对于客户端来说最可接受的媒体类型。HTTP 请求头部宣布接受什么是最容易被接受的。例如,如果接受头部是 Accept: text/plain
然后dogetasplaintext 方法会被调用。如果接受标题是Accept: text/plain;q=0.9, text/htm
,即客户可以接受 text/plain
和 text/html
,但更容易接收后者的媒体类型,然后 dogetashtml 方法会被调用。
@Produces 可以定义多个返回类型,例如:
Example 3.5. 使用多个返回类型
@GET
@Produces({"application/xml", "application/json"})
public String doGetAsXmlOrJson() {
...
}
无论application/xml
或者application/json
哪个匹配上了,都会执行 doGetAsXmlOrJson,如果两个都匹配了,那么会选择首先匹配的那个。
服务器也可选的指定个别媒体类型的品质因数。这些是客户端的决定的如何才是可接受的。例如:
Example 3.6. 服务器端内容协商
@GET
@Produces({"application/xml; qs=0.9", "application/json"})
public String doGetAsXmlOrJson() {
...
}
在上面的示例,如果客户端是接受application/xml
或者 application/json
,那么服务器总是发送application/json
,因为 application/xml
有一个较低的品质因数。
上面的例子是指明确清楚的 MIME 媒体类型。最好让它用常量来表示,这样可能会降低印刷错误。具体见 MediaType的常量字段值。
3.1.4. @Consumes
@Consumes注释是用来指定表示可由资源消耗的 MIME 媒体类型。上面的例子可以修改设置如下:
Example 3.7. 指定输入 MIME 类型:
@POST
@Consumes("text/plain")
public void postClichedMessage(String message) {
// Store the message
}
在这个例子中,该 Java 方法将消耗表示确定的 MIME 媒体类型text/plain
。注意资源的方法返回 void 。这意味着没有内容返回,而是一个204 状态码响应(204是指“无内容”)将返回到客户端。
@Consumes既可以应用在类的水平上,也可以作用与方法的水平,而且声明可以不只一种类型。